
// 行为树扩展定义
namespace GameToolkit.BehaviourTree
{
    /// <summary>
    /// 行为树根节点执行回调（所有 BehaviourTreeObject 实现该接口可回调）
    /// </summary>
    public interface IExecutableRootCallback
    {
        /// <summary>
        /// 根节点 OnStart 之前执行
        /// </summary>
        /// <param name="player"></param>
        void OnStart(BehaviourTreePlayer player);
        /// <summary>
        /// 根节点 OnStop 之后执行
        /// </summary>
        /// <param name="player"></param>
        void OnStop(BehaviourTreePlayer player);
    }

    /// <summary>
    /// （行为树）节点执行回调。（当装饰节点实现该接口，可同步执行节点的回调事件）
    /// </summary>
    public interface IExecutableEntryCallback
    {
        /// <summary>
        /// node OnStart 之后执行
        /// </summary>
        /// <param name="player"></param>
        void OnStart(BehaviourTreePlayer player);
        /// <summary>
        /// node OnStop 之前执行
        /// </summary>
        /// <param name="player"></param>
        void OnStop(BehaviourTreePlayer player);
    }

    /// <summary>
    /// （行为树）节点更新回调。（当装饰节点或控制节点实现该接口，可同步执行其绑定节点或子节点的更新回调）
    /// 注意，当某一个 ActionNode 在执行更新时，其自身和所有父节点中的该接口都将被执行。
    /// </summary>
    public interface IExecutableUpdateCallback
    {
        void OnUpdate(BehaviourTreePlayer player, ExecutableEntry actionNode);
    }

    /// <summary>
    /// 中断信号， 当装饰节点实现该接口，可以覆盖行为节点的执行状态
    /// </summary>
    public interface IInterruptionSource
    {
        // 返回中断状态
        NodeState GetInterruptResult(BehaviourTreePlayer player);
        // 返回组合条件中的“非门”中断状态
        NodeState GetNotInterruptResult(BehaviourTreePlayer player);
    }

    /// <summary>
    /// 循环执行控制器
    /// </summary>
    public interface ILoopController
    {
        /// <summary>
        /// 初始化新的循环周期
        /// </summary>
        /// <param name="player"></param>
        void OnResetLoop(BehaviourTreePlayer player);
    }

    /// <summary>
    /// 行为树运行时对象基类
    /// </summary>
    public abstract partial class BehaviourTreeObject
    {
        public Composite composite => mComposite;

        /// <summary>
        /// 行为树被创建时回调
        /// </summary>
        /// <param name="player"></param>
        protected abstract void OnCreate(BehaviourTreePlayer player);
        /// <summary>
        /// 行为树被销毁时回调
        /// </summary>
        /// <param name="player"></param>
        protected abstract void OnDestroy(BehaviourTreePlayer player);
    }

    /// <summary>
    /// （行为树）节点基类
    /// </summary>
    public abstract partial class ExecutableEntry : BehaviourTreeObject
    {
        /// <summary>
        /// 所属父节点
        /// </summary>
        public ExecutableEntry Parent => mParent;
        /// <summary>
        /// 装饰节点数量
        /// </summary>
        public int DecoratorCount => mDecorators == null ? 0 : mDecorators.Length;
        /// <summary>
        /// 获取装饰节点
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Decoration GetDecorator(int index) { return mDecorators[index]; }
        /// <summary>
        /// 当前节点是否可执行(Invoke before OnStart)
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        protected virtual bool IsExecutable(BehaviourTreePlayer player) { return true; }

        /// <summary>
        /// 节点开始执行时回调 (before first update)
        /// </summary>
        /// <param name="player"></param>
        protected abstract void OnStart(BehaviourTreePlayer player);
        /// <summary>
        /// 节点执行结束时回调 (after last update)
        /// </summary>
        /// <param name="player"></param>
        protected abstract void OnStop(BehaviourTreePlayer player);
        /// <summary>
        /// 节点被中断执行（条件不满足或获得中断信号）时回调
        /// </summary>
        /// <param name="player"></param>
        /// <param name="successInterruption"></param>
        /// <returns></returns>
        protected virtual NodeState OnInterrupt(BehaviourTreePlayer player, bool successInterruption)
        {
            return successInterruption ? NodeState.Success : NodeState.Failed;
        }
    }

    /// <summary>
    /// 装饰节点
    /// </summary>
    public abstract partial class Decoration : BehaviourTreeObject
    {

    }

    /// <summary>
    /// 条件节点
    /// </summary>
    public abstract partial class Condition : Decoration
    {
        public abstract bool IsTrue(BehaviourTreePlayer player/*, ExecutableEntry attachNode*/);
    }

    /// <summary>
    /// （行为树）控制节点
    /// </summary>
    public abstract partial class ControllerNode : ExecutableEntry
    {
        /// <summary>
        /// 获取接下来将要执行的行为节点
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        protected abstract NodeState GetNextBehaviour(BehaviourTreePlayer player, out ExecutableEntry nextNode);
    }

    /// <summary>
    /// （行为树）行为节点
    /// </summary>
    public abstract partial class ActionNode : ExecutableEntry
    {
        /// <summary>
        /// 节点更新回调（每帧调用，对于后台执行的行为，可能每若干帧才会执行一次）
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        protected abstract NodeState OnUpdate(BehaviourTreePlayer player);
    }

}
